package com.ruoyi.system.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.vo.InspectionPeriodVO;
import com.ruoyi.system.entity.*;
import com.ruoyi.system.mapper.InspectionPlanMapper;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.service.*;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.*;

/**
 * (InspectionPlan)表服务实现类
 * @author makejava
 * @since 2022-11-25 17:09:56
 */
@Service("inspectionPlanService")
public class InspectionPlanServiceImpl implements InspectionPlanService {
    @Resource
    private InspectionPlanMapper inspectionPlanDao;

    @Resource
    private InspectionPlanTaskService inspectionPlanTaskService;

    @Resource
    private InspectionPlanTaskDetailsService inspectionPlanTaskDetailsService;

    @Resource
    private InspectionPointService inspectionPointService;

    @Resource
    private ISysUserService userService;

    @Resource
    private SysActingService sysActingService;

    @Resource
    private SysRemindService sysRemindService;

    @Resource
    private InspectionPeriodService inspectionPeriodService;

    @Resource
    private InspectionRouteService inspectionRouteService;

    @Resource
    private SysUserMapper sysUserMapper;

    @Resource
    private EnterpriseWXServiceImpl enterpriseWXService;
    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public InspectionPlan queryById(Integer id) {
        return this.inspectionPlanDao.queryById(id);
    }

    /**
     * 分页查询
     *
     * @param inspectionPlan 筛选条件
     * @return 查询结果
     */
    @Override
    public List<InspectionPlan> queryByPage(InspectionPlan inspectionPlan) {
        return inspectionPlanDao.queryAllByLimit(inspectionPlan);
    }

    /**
     * 新增数据
     *
     * @param inspectionPlan 实例对象
     * @return 实例对象
     */
    @Override
    public InspectionPlan insert(InspectionPlan inspectionPlan) {
        inspectionPlan.setFbState(1);
        inspectionPlan.setCheckStatus(1);
        inspectionPlan.setCheckJd("待审核");
        inspectionPlan.setInitiatorId(SecurityUtils.getUserId().intValue());
        inspectionPlan.setInitiatorName(SecurityUtils.getUsername());
        this.inspectionPlanDao.insert(inspectionPlan);
        return inspectionPlan;
    }

    /**
     * 修改数据
     *
     * @param inspectionPlan 实例对象
     * @return 实例对象
     */
    @Override
    public InspectionPlan update(InspectionPlan inspectionPlan) {
        this.inspectionPlanDao.update(inspectionPlan);
        return this.queryById(inspectionPlan.getId());
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Integer id) {
        return this.inspectionPlanDao.deleteById(id) > 0;
    }


    @Scheduled(cron = "0/60 * * * * ?")
    public void createTask() {
        InspectionPlan inspectionPlan = new InspectionPlan();
        List<InspectionPlan> inspectionPlans = inspectionPlanDao.queryAllByLimit(inspectionPlan);
        if (CollUtil.isNotEmpty(inspectionPlans)){
            for (InspectionPlan i : inspectionPlans) {
                DateTime now = DateUtil.date();
                DateTime planStart = DateUtil.parse(i.getStartTime(), "yyyy-MM-dd HH:mm:ss");
                Date planSTime = planStart.toJdkDate();
                boolean after2 = planSTime.after(now);

                DateTime planEnd = DateUtil.parse(i.getEndTime(), "yyyy-MM-dd HH:mm:ss");
                Date planETime = planEnd.toJdkDate();
                boolean after3 = planETime.after(now);
                if (after2 || !after3) {
                    // 未到开始时间或已超过结束时间
                    continue;
                }
                InspectionRoute inspectionRoute = inspectionRouteService.queryById(i.getRouteId());
                if (inspectionRoute.getStopCheck() == 1) {
                    continue;
                }
                if (i.getFbState() == 1 || i.getCheckStatus() == 3 || i.getCheckStatus() == 1) {
                    continue;
                }
                List<InspectionPeriodVO>  inspectionPeriodVOList = inspectionPeriodService.queryListById(i.getPeriodId());
                if (CollUtil.isNotEmpty(inspectionPeriodVOList)){
                    String today = DateUtil.today();
                    Map<String,String> map = new HashMap<>();
                    for (InspectionPeriodVO inspectionPeriodVO : inspectionPeriodVOList) {
                        Integer intervalDate = Integer.valueOf(i.getFrequencyType());
                        if (intervalDate >= 1) {
                            String planStartTime = today + " " + inspectionPeriodVO.getStartDate();
                            DateTime parse = DateUtil.parse(planStartTime, "yyyy-MM-dd HH:mm:ss");
                            Date date = parse.toJdkDate();
                            boolean after = date.after(now);

                            String s = DateUtil.offsetDay(now, intervalDate).toString("yyyy-MM-dd");
                            String planEndTime = s + " " + inspectionPeriodVO.getEndDate();
                            DateTime endTime = DateUtil.parse(planEndTime, "yyyy-MM-dd HH:mm:ss");
                            Date end = endTime.toJdkDate();
                            boolean endAfter = end.after(now);

                            if (!after && endAfter) {
                                map.put("start",planStartTime);
                                map.put("end",planEndTime);
                                break;
                            }
                        } else {
                            String planStartTime = today + " " + inspectionPeriodVO.getStartDate();
                            DateTime parse = DateUtil.parse(planStartTime, "yyyy-MM-dd HH:mm:ss");
                            Date date = parse.toJdkDate();
                            boolean after = date.after(now);
                            String planEndTime = today + " " + inspectionPeriodVO.getEndDate();
                            DateTime endTime = DateUtil.parse(planEndTime, "yyyy-MM-dd HH:mm:ss");
                            Date end = endTime.toJdkDate();
                            if (!end.after(date)) {
                                DateTime tomorrow = DateUtil.tomorrow();
                                String s = tomorrow.toString("yyyy-MM-dd");
                                planEndTime = s + " " + inspectionPeriodVO.getEndDate();
                                endTime = DateUtil.parse(planEndTime, "yyyy-MM-dd HH:mm:ss");
                                end = endTime.toJdkDate();
                            }
                            boolean endAfter = end.after(now);
                            if (!after && endAfter) {
                                map.put("start",planStartTime);
                                map.put("end",planEndTime);
                                break;
                            }
                        }
                    }
                    if (CollUtil.isNotEmpty(map)) {
                        InspectionPlanTask byPlanId = inspectionPlanTaskService.queryByPlanId(i.getId());
                        InspectionPlanTask inspectionPlanTask = new InspectionPlanTask();
                        if (byPlanId == null) {
                            inspectionPlanTask.setPlanId(i.getId());
                            inspectionPlanTask.setPlanUserNames(i.getPlanUserNames());
                            inspectionPlanTask.setPlanUserIds(i.getPlanUserIds());
                            inspectionPlanTask.setRouteId(i.getRouteId());
                            inspectionPlanTask.setRouteName(i.getRouteName());
                            inspectionPlanTask.setPlanTaskState("未完成");
                            inspectionPlanTask.setStartTime(map.get("start"));
                            inspectionPlanTask.setEndTime(map.get("end"));
                            inspectionPlanTaskService.insert(inspectionPlanTask);
                            createTaskDetails(inspectionPlanTask);
                        } else {
                            String byPlanIdEndTime = byPlanId.getEndTime();
                            DateTime dateTime = DateUtil.parse(byPlanIdEndTime, "yyyy-MM-dd HH:mm:ss");
                            Date date1 = dateTime.toJdkDate();
                            boolean after1 = date1.after(now);
                            if (!after1) {
                                inspectionPlanTask.setPlanId(i.getId());
                                inspectionPlanTask.setPlanUserNames(i.getPlanUserNames());
                                inspectionPlanTask.setPlanUserIds(i.getPlanUserIds());
                                inspectionPlanTask.setRouteId(i.getRouteId());
                                inspectionPlanTask.setRouteName(i.getRouteName());
                                inspectionPlanTask.setPlanTaskState("未完成");
                                inspectionPlanTask.setStartTime(map.get("start"));
                                inspectionPlanTask.setEndTime(map.get("end"));
                                inspectionPlanTaskService.insert(inspectionPlanTask);
                                createTaskDetails(inspectionPlanTask);
                            }
                        }
                        if (inspectionPlanTask.getId() != null) {
                            // 新增待办
                            List<SysActing> sysActings = new ArrayList<>();
                            // 获取任务详情
                            String planUserIds = inspectionPlanTask.getPlanUserIds();
                            String[] ids = planUserIds.split(",");
                            for (String idStr : ids) {
                                Long id = Long.parseLong(idStr);
                                SysUser sysUser = userService.selectUserById(id);
                                String userName = sysUser.getUserName();
                                SysActing sysActing = new SysActing();
                                sysActing.setTitleName("巡检");
                                sysActing.setTitleType("巡检任务");
                                sysActing.setTitleInfo(i.getPlanName());
                                sysActing.setExecutorName(userName);
                                sysActing.setExecutorId(id.intValue());
                                sysActing.setSourceId(inspectionPlanTask.getId());
                                sysActing.setOriginatorId(1);
                                sysActing.setOriginatorName("admin");
                                sysActings.add(sysActing);
                            }
                            sysActingService.insertBatch(sysActings);
                        }
                    }
                }
            }
        }
    }




//    @Scheduled(cron = "0 0 0 1/1 * ? ")
    @Scheduled(cron = "0/60 * * * * ?")
    public void checkPoint() {
        InspectionPlanTask inspectionPlanTask = new InspectionPlanTask();
        inspectionPlanTask.setPlanTaskState("未完成");
        List<InspectionPlanTask> inspectionPlanTasks = inspectionPlanTaskService.queryByPage(inspectionPlanTask);
        List<SysRemind> sysReminds = new ArrayList<>();
        inspectionPlanTasks.forEach(i -> {
            DateTime now = DateUtil.date();
            String planEndTime = i.getEndTime();
            DateTime endTime = DateUtil.parse(planEndTime, "yyyy-MM-dd HH:mm:ss");
            Date end = endTime.toJdkDate();
            boolean endAfter = end.after(now);
            if (!endAfter) {
                i.setPlanTaskState("已超时");
                inspectionPlanTaskService.update(i);
                InspectionPlan inspectionPlan = inspectionPlanDao.queryById(i.getPlanId());
                InspectionPlanTaskDetails inspectionPlanTaskDetails = new InspectionPlanTaskDetails();
                inspectionPlanTaskDetails.setPlanTaskId(i.getId());
                inspectionPlanTaskDetails.setCheckState("未排查");
                List<InspectionPlanTaskDetails> inspectionPlanTaskDetailsList = inspectionPlanTaskDetailsService.queryByPage(inspectionPlanTaskDetails);
                if (CollUtil.isNotEmpty(inspectionPlanTaskDetailsList)) {
                    inspectionPlanTaskDetailsList.forEach(taskDetails -> {
                        StringBuffer stringBuffer = new StringBuffer();
                        stringBuffer.append("该");
                        stringBuffer.append(inspectionPlan.getPlanName());
                        stringBuffer.append("巡检计划有漏捡点位: ");
                        stringBuffer.append(taskDetails.getPointName());
                        String planUserIds = i.getPlanUserIds();
                        String[] split = planUserIds.split(",");
                        for (int i1 = 0; i1 < split.length; i1++) {
                            SysRemind sysRemind = new SysRemind();
                            sysRemind.setRemindType(SysRemind.TYPE_MONITOR);
                            sysRemind.setRemindContent(stringBuffer.toString());
                            sysRemind.setRemindUserId(Integer.valueOf(split[i1]));
                            sysReminds.add(sysRemind);
                        }
                    });
                }
                sengwx(i);
            }
        });
        if (StringUtils.isNotEmpty(sysReminds)) {
            sysRemindService.insertBatch(sysReminds);
        }
    }

    public void createTaskDetails(InspectionPlanTask inspectionPlanTask) {
        Integer routeId = inspectionPlanTask.getRouteId();
        InspectionPoint inspectionPoint = new InspectionPoint();
        inspectionPoint.setRouteId(routeId);
        List<InspectionPoint> inspectionPoints = inspectionPointService.queryByPage(inspectionPoint);
        List<InspectionPlanTaskDetails> inspectionPlanTaskDetailsList = new ArrayList<>();
        inspectionPoints.forEach(i -> {
            if (i.getStopCheck() == 0) {
                InspectionPlanTaskDetails inspectionPlanTaskDetails = new InspectionPlanTaskDetails();
                inspectionPlanTaskDetails.setPlanTaskId(inspectionPlanTask.getId());
                inspectionPlanTaskDetails.setPointId(i.getId());
                inspectionPlanTaskDetails.setPointName(i.getPointName());
                inspectionPlanTaskDetails.setCheckState("未排查");
                inspectionPlanTaskDetailsList.add(inspectionPlanTaskDetails);
            }
        });
        inspectionPlanTaskDetailsService.insertBatch(inspectionPlanTaskDetailsList);
    }





    /**
     *  审核
     * @param
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateInspectionPlanState(InspectionPlan inspectionPlan) {
        InspectionPlan plan = inspectionPlanDao.queryById(inspectionPlan.getId());
        Integer userId = SecurityUtils.getUserId().intValue();
        if (!userId.equals(plan.getPersonId())) {
            throw new ServiceException("您无权操作此条巡检计划记录",500);
        }
        if (inspectionPlan.getCheckStatus() == 2) {
            inspectionPlan.setCheckJd("已审核");
        } else {
            inspectionPlan.setCheckJd("已驳回");
        }
        inspectionPlanDao.update(inspectionPlan);
        // 审核完成-完成待办任务-待整改状态-创建整改待办提醒
        sysActingService.completeActing("巡检计划","审核",plan.getId());
        if (plan.getCheckStatus() == 1) {
            SysActing sysActing = new SysActing();
            sysActing.setTitleName("巡检计划");
            sysActing.setTitleType("通过");
            sysActing.setExecutorName(plan.getPersonName());
            sysActing.setExecutorId(plan.getPersonId());
            sysActing.setSourceId(plan.getId());
            sysActing.setOriginatorId(plan.getInitiatorId());
            sysActing.setOriginatorName(plan.getInitiatorName());
            sysActingService.insert(sysActing);
        }

    }


    @Async
    public void sengwx(InspectionPlanTask inspectionPlanTask) {
        List<Integer> userIds = sysUserMapper.selectUserByPostName("巡检逾期推送");
        EnterpriseWXServiceImpl.SendMessageRequest sendMessageRequest = new EnterpriseWXServiceImpl.SendMessageRequest();
        sendMessageRequest.setTouser(CollUtil.join(userIds,"|"));
        sendMessageRequest.setMsgtype("text");
        sendMessageRequest.setAgentid(1000319);
        EnterpriseWXServiceImpl.MessageContent messageContent = new EnterpriseWXServiceImpl.MessageContent();
        messageContent.setContent("巡检任务逾期预警:（" + inspectionPlanTask.getStartTime() + "至" + inspectionPlanTask.getEndTime() + "-" + inspectionPlanTask.getPlanName() + " 已逾期,请监督巡检人员完成后续巡检任务！）");
        sendMessageRequest.setText(messageContent);
        enterpriseWXService.pushMessage(sendMessageRequest);
    }
}
